package com.mutouren.web;

import java.util.UUID;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.mutouren.common.cache.impl.CacheManager;
import com.mutouren.common.entity.ResultCode;
import com.mutouren.common.entity.ResultInfo;
import com.mutouren.common.entity.ValidState;
import com.mutouren.common.log.LogAlias;
import com.mutouren.common.log.LogManager;
import com.mutouren.common.log.Logger;
import com.mutouren.common.session.UserInfo;
import com.mutouren.common.thread.ThreadPoolManager;
import com.mutouren.modules.org.entity.IdentityType;
import com.mutouren.modules.org.model.Person;
import com.mutouren.modules.org.service.PersonService;
import com.mutouren.modules.sso.client.MappingUser;
import com.mutouren.modules.sso.client.SsoRequestFilter;

public class ContextListener implements ServletContextListener {
	
	private static Logger runLogger = LogManager.getLogger(LogAlias.SystemRun.name());
	private static Logger errorLogger = LogManager.getLogger(LogAlias.SystemError.name());
	
	private WebApplicationContext webApplicationContext;

	@Override
	public void contextDestroyed(ServletContextEvent arg0) {
		ServletContext context = arg0.getServletContext();
		
		runLogger.info(String.format("mutouren system destroy, contextPath: %s, applicationId: %s", 
				context.getContextPath(), context.getAttribute("applicationId")));	
		
		close();
	}

	@Override
	public void contextInitialized(ServletContextEvent arg0) {
		ServletContext context = arg0.getServletContext();
		context.setAttribute("applicationId", UUID.randomUUID().toString());
		context.setAttribute("ctx", context.getContextPath());
		
		runLogger.info(String.format("mutouren system initialize, contextPath: %s, applicationId: %s", 
				context.getContextPath(), context.getAttribute("applicationId")));

		webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(context);
		displayBeans_debug();
		open();
	}
	
	//@SuppressWarnings("unused")
	private void displayBeans_debug() {
		for(String alias :  webApplicationContext.getBeanDefinitionNames()) {
			Object obj = webApplicationContext.getBean(alias);
			System.out.println(String.format("springbean %s: %s", alias, obj.getClass()));
		}
	}
	
	private void open() {	
		try {		
			runLogger.info("mutouren openJob start.");
			
			// 系统配置
			SystemConfig.init(webApplicationContext);			
			// 组织权限
			AuthorityManager.init(webApplicationContext);
			
			// SSO初始化映射
			SsoRequestFilter.initMappingUser(createMappingUser());
			
			runLogger.info("mutouren openJob finish.");
		} catch(Throwable t) {
			errorLogger.error("mutouren openJob error.", t);
		}
	}
	
	private MappingUser createMappingUser() {
		
		PersonService personService = webApplicationContext.getBean(PersonService.class);
		
		return new MappingUser() {

			@Override
			public ResultInfo<UserInfo> mapping(UserInfo userInfo) {
				ResultInfo<UserInfo> result = new ResultInfo<UserInfo>();
				
				Person person = personService.getByIdentity(userInfo.getEmail(), IdentityType.email);
				if ((person == null) || (person.getValidState() != ValidState.Normal)) {
					result.setCode(ResultCode.FAIL.value);
					result.setMessage("身份不存在或无效");
					return result;
				}
				
				result.setCode(ResultCode.SUCCESS.value);
				result.setInfo(convertToUserInfo(person));				
				return result;
			}
			
		};
	}
	
	private UserInfo convertToUserInfo(Person person) {		
		UserInfo result = new UserInfo();
		result.setUserId(person.getPersonId());
		result.setUserName(person.getLoginName());
		result.setOrgId(person.getOrgId());
		
		return result;
	}	
	
	private void close() {
		try {
			ThreadPoolManager.close();
			CacheManager.close();
			runLogger.info("mutouren closeJob finish");
		} catch(Throwable t) {
			errorLogger.error("mutouren closeJob error.", t);
		}
		
		// 关闭日志
		LogManager.close();		
	}
}
